home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / sonido / mod-0.000 / mod-0 / mod / load_mtm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-15  |  9.8 KB  |  428 lines

  1. /*
  2.  *  load_mtm.c - Loads Multitracker modules.
  3.  *
  4.  *  (C) 1994 Mikael Nordqvist (d91mn@efd.lth.se, mech@df.lth.se)
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <sys/types.h>
  11. #include <fcntl.h>
  12. #include <sys/ioctl.h>
  13. #include <sys/soundcard.h>
  14. #include <sys/ultrasound.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18.  
  19. #include "mod.h"
  20.  
  21. /* External global variables */
  22.  
  23. SEQ_DECLAREBUF();
  24. extern int seqfd, gus_dev;
  25.  
  26. extern struct mod_info M;
  27. extern struct options opt;
  28.  
  29. extern char quit;
  30.  
  31. extern char effect_used[NR_EFX];
  32.  
  33. /* Local functions */
  34.  
  35. static int process_header(int);
  36. static int read_patterndata(int);
  37. static void fix_effect(unsigned char *, unsigned char *);
  38.  
  39. /* Defines and variables used while loading module */
  40.  
  41. #define MTM_HEADER_SIZE     66 
  42. #define MTM_SAMPLEINFO_SIZE 37
  43.  
  44. #define MTM_MAGIC          0
  45. #define MTM_VERSION        3
  46. #define MTM_NAME           4
  47. #define MTM_TRACKS        24
  48. #define MTM_PATTERNS      26
  49. #define MTM_SONGLENGTH    27
  50. #define MTM_COMMENT_LEN   28
  51. #define MTM_NOS           30
  52. #define MTM_UNUSEDATTR    31
  53. #define MTM_BPT           32
  54. #define MTM_PLAYEDTRACKS  33
  55. #define MTM_PANPOS        34
  56.  
  57. #define MTM_S_NAME         0
  58. #define MTM_S_LEN         22
  59. #define MTM_S_LOOPSTART   26
  60. #define MTM_S_LOOPEND     30
  61. #define MTM_S_FINETUNE    34
  62. #define MTM_S_VOLUME      35
  63. #define MTM_S_ATTR        36
  64.  
  65. #define MTM_FLAG_BITS_16   1
  66.  
  67. static int expected_length, tracks, commentlen;
  68.  
  69. int load_mtm(int fd)
  70. {
  71.     char tmpbuf[80];
  72.  
  73.     int i, diff, fatalerr;
  74.  
  75.     print_status("Loading MTM");
  76.     M.nr_tracks=0;
  77.  
  78.     if(!process_header(fd))
  79.     return 0;
  80.  
  81.     if(!read_patterndata(fd)) {
  82.     info("Unable to read patterndata.\n");
  83.     return 0;
  84.     }
  85.     
  86.     ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev);
  87.     
  88.     info("\nUploading instruments to GUS...\n");
  89.     
  90.     fatalerr=0;
  91.  
  92.     for(i=1; i <= M.nr_samples; ++i) {
  93.     if(M.sample[i].length > 4) { /* Only load non-silent samples */
  94.         if(!read_and_upload_sample(fd, i)) {
  95.         fatalerr=1;
  96.         break;
  97.         }
  98.     }
  99.     else { /* Skip sample */
  100.         if(lseek(fd, M.sample[i].length, SEEK_CUR) == -1){
  101.         fatalerr=1;
  102.         break;
  103.         }
  104.     }
  105.     if(quit == QUIT_SIGNAL) /* Bail out if we got QUIT_SIGNAL */
  106.         return 0;
  107.     }
  108.  
  109.     if(fatalerr) {
  110.     diff=expected_length-lseek(fd, 0, SEEK_CUR);
  111.     sprintf(tmpbuf, "File %d bytes short", diff);
  112.     print_status(tmpbuf);
  113.     info("\nShort file (%d bytes missing).\n",0);
  114.     sleep(1);
  115.     return 0;
  116.     }
  117.     
  118.     /* Check if filelength was as expected. This is done with two 
  119.      * statements to make sure we don't move the filepointer to the 
  120.      * end before checking current position.
  121.      */
  122.  
  123.     diff=-lseek(fd, 0, SEEK_CUR);
  124.     diff+=lseek(fd, 0, SEEK_END);
  125.  
  126.     if(diff && opt.verbose) {
  127.     warning("\nFound %d garbagebytes after samples. Ignoring.\n", diff);
  128.     }
  129.     
  130.     print_songname(M.name);
  131.     print_samples(1);
  132.     print_songinfo(M.nr_voices, M.nr_samples, "MTM", expected_length,
  133.            M.songlength, M.nr_patterns);
  134.     return 1;
  135. }
  136.  
  137.  
  138. static int process_header(int fd)
  139. {
  140.     unsigned char buf[MTM_HEADER_SIZE];
  141.     int tmp, i;
  142.     struct sample_info *s;
  143.     
  144.     if(read(fd, buf, MTM_HEADER_SIZE) != MTM_HEADER_SIZE) {
  145.     info("Unable to read header from file.\n");
  146.     return 0;
  147.     }
  148.     
  149.     expected_length=MTM_HEADER_SIZE; /* Start counting expected filesize */
  150.     
  151.     if(strncmp("MTM", &buf[MTM_MAGIC], 3)) {
  152.     info("Not a Multitracker module.\n");
  153.     return 0;
  154.     }
  155.     
  156.     info("Format version %d.%d\n", (buf[MTM_VERSION]>>4)&0x0f,
  157.      buf[MTM_VERSION]&0x0f);
  158.     
  159.     /* Copy songname and strip trailing spaces */
  160.     strncpy(M.name, &buf[MTM_NAME], 20);
  161.     M.name[20]=0;
  162.     fix_string(M.name);
  163.  
  164.     tracks=*(unsigned short *)&buf[MTM_TRACKS];
  165.     M.nr_patterns=buf[MTM_PATTERNS]+1;
  166.     M.songlength=buf[MTM_SONGLENGTH]+1;
  167.     commentlen=*(unsigned short *)&buf[MTM_COMMENT_LEN];
  168.     M.nr_samples=buf[MTM_NOS];
  169.  
  170.     info("Tracks saved: %d\n", tracks);
  171.  
  172.     if(!M.nr_samples || M.nr_samples > 127) {
  173.     info("Invalid number of samples in module.\n");
  174.     return 0;
  175.     }
  176.  
  177.     if(M.nr_patterns > 127) {
  178.     info("Invalid number of patterns.\n");
  179.     return 0;
  180.     }
  181.  
  182.     if(buf[MTM_BPT] != 64) {
  183.     info("Beats (lines) per track: %d (!=64!).\n", buf[MTM_BPT]);
  184.     return 0;
  185.     }
  186.     
  187.     M.sample=(struct sample_info *)malloc((1+M.nr_samples)*
  188.                       sizeof(struct sample_info));
  189.  
  190.     expected_length+=M.nr_samples*MTM_SAMPLEINFO_SIZE;
  191.     print_sample_info_header();
  192.  
  193.     for(i=1; i <= M.nr_samples; ++i) {
  194.     if(read(fd, buf, MTM_SAMPLEINFO_SIZE) != MTM_SAMPLEINFO_SIZE) {
  195.         info("Unable to read sampleheader (%d).\n", i);
  196.         return 0;
  197.     }
  198.     
  199.     s=&M.sample[i];
  200.         s->valid=0;             /* Valid isn't set to TRUE until it's
  201.                  * sampledata has been read.
  202.                  */
  203.     strncpy(s->name, &buf[MTM_S_NAME], 22);
  204.     s->name[22]=0;
  205.         fix_string(s->name);
  206.     
  207.     s->length=*(unsigned long *)&buf[MTM_S_LEN];
  208.     s->repeat_start=*(unsigned long *)&buf[MTM_S_LOOPSTART];
  209.     s->repeat_end=*(unsigned long *)&buf[MTM_S_LOOPEND];
  210.     s->finetune=buf[MTM_S_FINETUNE];
  211.     s->volume=buf[MTM_S_VOLUME];
  212.  
  213.         s->c2freq=-1; /* Use PAL/NTSC */
  214.     
  215.     if(buf[MTM_S_ATTR]&MTM_FLAG_BITS_16)
  216.         s->bits_16=1;
  217.     else
  218.         s->bits_16=0;
  219.  
  220.     if(s->repeat_end > s->repeat_start+4)
  221.         s->looped=LOOP_FORWARD;
  222.     else
  223.         s->looped=0;
  224.     
  225.     s->unsigned_data=1;
  226.  
  227.     s->repeat_start=MIN(MAX(0, s->repeat_start), s->length-2);
  228.     
  229.     /* Is this one including/excluding the last sample? */
  230.     s->repeat_end=MIN(MAX(0, s->repeat_end), s->length-2);
  231.  
  232.     expected_length+=s->length;
  233.     
  234.     print_sample_info(i);
  235.     }
  236.  
  237.     if(read(fd, M.patterntable, 128) != 128) {
  238.     info("Unable to load patterntable.\n");
  239.     return 0;
  240.     }
  241.     expected_length+=128;
  242.  
  243.     for(i=0; i < 128; ++i)
  244.     if(M.patterntable[i] >= M.nr_patterns)
  245.         break;
  246.  
  247.     M.songlength=MIN(i, M.songlength);
  248.  
  249.     for(tmp=0; tmp < MAX_VOICES; ++tmp)
  250.     M.panning[tmp]=get_voice_balance(tmp);
  251.  
  252.     M.restartpos=0;
  253.     M.volrange=64;
  254.     
  255.     info("\nSamples: %d  Patterns: %d  Songlength: %d\n",
  256.      M.nr_samples, M.nr_patterns, M.songlength);
  257.     
  258.     return 1;
  259. }
  260.  
  261.  
  262. static int read_patterndata(int fd)
  263. {
  264.     int track_mapping[128*32]; /* Maximum number of tracks */
  265.     unsigned char buf[2*32*128]; /* Max track seq. data */
  266.     char used_voices[32];
  267.     unsigned char *b;
  268.     unsigned short effect;
  269.     struct event *e;
  270.     int t, p, l, v, tmp;
  271.     struct event events[64];
  272.     
  273.     for(v=0; v < NR_EFX; ++v)
  274.     effect_used[v]=0;
  275.     
  276.     /* Allocate for worst case (no identical tracks) */
  277.     M.tracks=(struct event **)malloc(tracks*sizeof(struct event *));
  278.  
  279.     /* Add the empty track */
  280.     bzero((void *)events, sizeof(struct event)*64);
  281.     track_mapping[0]=get_track_idx(events);
  282.     
  283.     for(t=1; t <= tracks; ++t) {
  284.     if(read(fd, buf, 64*3) != 64*3)
  285.         return 0;
  286.     expected_length+=64*3;
  287.  
  288.     b=buf;
  289.     for(l=0; l < 64; ++l, b+=3) {
  290.         e=&events[l];
  291.         /* 2*12 because X-2 => X-4 */
  292.         e->note=(b[0]&0xfc ? ((b[0]&0xfc)>>2)+BASE_NOTE+2*12 : 0); 
  293.         e->sample=((b[0]&0x03)<<4)|((b[1]>>4)&0x0f);
  294.         effect=b[1]&0x0f;
  295.         
  296.         if(effect != 0x0e)
  297.         e->arg=b[2];
  298.         else {
  299.         effect=0x10|((b[2]>>4)&0x0f);
  300.         e->arg=b[2]&0x0f;
  301.         }
  302.         e->effect=effect;
  303.         fix_effect(&e->effect, &e->arg);
  304.         
  305.         if(e->effect ||e->arg)
  306.         effect_used[e->effect]=1;
  307.         
  308.         e->effect2=e->arg2=0;
  309.     }
  310.     track_mapping[t]=get_track_idx(events);
  311.     }
  312.     print_used_effects();
  313.     
  314.     if(read(fd, buf, M.nr_patterns*32*2) != M.nr_patterns*32*2)
  315.     return 0;
  316.     expected_length+=M.nr_patterns*32*2;
  317.     
  318.     bzero((void *)used_voices, 32);
  319.     for(p=0; p < M.nr_patterns; ++p)
  320.     for(v=0; v < 32; ++v)
  321.         if(track_mapping[*(unsigned short *)&buf[(p*32+v)*2]])
  322.         used_voices[v]=1;
  323.  
  324.     for(v=31; v >= 0 && !used_voices[v]; --v)
  325.     ;
  326.     M.nr_voices=v+1;
  327.     
  328.     if(!M.nr_voices) {
  329.     info("Song empty (no tracks used).\n");
  330.     return 0;
  331.     }
  332.     info("Used voices: %d\n", M.nr_voices);
  333.     
  334.     for(v=0; v < M.nr_voices; ++v)
  335.     M.track_idx[v]=(int *)malloc(M.nr_patterns*sizeof(int));
  336.  
  337.     for(p=0; p < M.nr_patterns; ++p) {
  338.     for(v=0; v < M.nr_voices; ++v) {
  339.         tmp=*(unsigned short *)&buf[(p*32+v)*2];
  340.         if(tmp > tracks) {
  341.         info("Illegal track specified (%d).\n", tmp);
  342.         return 0;
  343.         }
  344.         else {
  345.         M.track_idx[v][p]=track_mapping[tmp];
  346.         }
  347.     }
  348.     }
  349.     
  350.     /* C-0 through D#5 (before "transposing" 2 octaves) */
  351.     opt.low_note=BASE_NOTE+2*12;
  352.     opt.high_note=BASE_NOTE+7*12+4;
  353.  
  354.     if(commentlen) {
  355.     M.songtext=(void *)malloc(commentlen+1);
  356.     if(read(fd, M.songtext, commentlen) != commentlen) {
  357.         info("Unable to load comment.\n");
  358.         return 0;
  359.     }
  360.     *(M.songtext+commentlen)=0;
  361.     fix_string(M.songtext);
  362.     expected_length+=commentlen;
  363.     }
  364.     else
  365.     M.songtext=0;
  366.  
  367.     if(M.songtext && opt.verbose) {
  368.     printf("\n--------------- Message: ---------------\n");
  369.     tmp=0;
  370.     while(tmp < commentlen) {
  371.         printf("%.39s\n", &M.songtext[tmp]);
  372.         tmp+=40;
  373.     }
  374.     printf("----------------------------------------\n");
  375.     }
  376.  
  377.     return 1;
  378. }
  379.  
  380. /* Filters out those effects not supported by Multitracker and adds the
  381.  * balance-effect.
  382.  */
  383.  
  384. static void fix_effect(unsigned char *effect, unsigned char *arg)
  385. {
  386.     switch(*effect) {
  387.       case EFX_ARPEGGIO:           /* Effects compatible with PT */
  388.       case EFX_PORTAUP:
  389.       case EFX_PORTADOWN:
  390.       case EFX_PORTANOTE:
  391.       case EFX_VIBRATO:
  392.       case EFX_PORTANOTEVOLSLIDE:
  393.       case EFX_VIBRATOVOLSLIDE:
  394.       case EFX_TREMOLO:
  395.       case EFX_UNUSED1:
  396.       case EFX_SAMPLEOFFSET:
  397.       case EFX_VOLSLIDE:
  398.       case EFX_JUMP:
  399.       case EFX_VOLUME:
  400.       case EFX_BREAK:
  401.       case EFX_FINEPORTAUP:
  402.       case EFX_FINEPORTADOWN:
  403.       case EFX_FINETUNE:
  404.       case EFX_RETRIGGER:
  405.       case EFX_FINEVOLSLIDEUP:
  406.       case EFX_FINEVOLSLIDEDOWN:
  407.       case EFX_NOTECUT:
  408.       case EFX_NOTEDELAY:
  409.       case EFX_PTSPEED:
  410.     break;
  411.  
  412.       case EFX_UNUSED2:           /* MTM: Balance */
  413.     *effect=EFX_BALANCE;
  414.     break;
  415. #if 0    
  416.       /* These effects are not supported by Multitracker */
  417.       case EFX_FILTER:
  418.       case EFX_GLISSANDO:
  419.       case EFX_VIBWAVEFORM:
  420.       case EFX_LOOP:
  421.       case EFX_TREMWAVEFORM:
  422.       case EFX_INVERTEDLOOP:
  423. #endif
  424.       default:
  425.     *effect=*arg=0;
  426.     }
  427. }
  428.